import { Component, Host, ViewChild } from "@angular/core";
import { AppComponent } from "../../../app.component";
import { ActivatedRoute, Router } from "@angular/router";
import { CriteriaResultModel } from "../models/criteriaResult.model";
import { FilterModel, FilterType } from "../models/filter.model";
import { TargetType, ReportingService } from "../reporting.service";
import { CriteriaComponent } from "./criteria/criteria.component";
import { Subscription } from "rxjs";
import { BaseTemplateOutput } from "./criteria/template/models/save/criteriaTemplateOutput.models";
import { SearchType } from "../../../shared/components/search/search.service";
import { StorageService } from "../../../shared/services/storage.service";
import { Profile } from "../../../framework/login/models/profile.model";
import { ResultsComponent } from "./results/results.component";
import { CriteriaListingComponent } from "./criteriaListing/criteriaListing.component";
import { ModalComponent } from "../../../shared/components/modal/modal.component";
import { AnalyticsService } from "../../../shared/services/googleAnalytics.service";
import { GoogleAnalyticsBeacon } from "../../../shared/models/googleAnalytics.model";

@Component({
    templateUrl: 'filter.component.html',
    styleUrls: ['../reporting.component.scss'],
    providers: [ReportingService]
})
export class FilterComponent {
    private editSub: Subscription;
    private levelSub: Subscription;
    private updateSub: Subscription;
    public targetType: typeof TargetType = TargetType;
    public filterType: typeof FilterType = FilterType;
    public searchType: SearchType = SearchType.portfolio;
    private editingFilterGroupId: string;
    public filterId: string;
    public filter: FilterModel;
    public editCriteriaMode: boolean = false;
    public editNameMode: boolean = false;
    public editCriteriaLevel1Id: string;
    public editCriteriaLevel2Id: string;
    private shortName: string;
    public owner: Profile;
    public elementCount: number = 0;
    public type: TargetType;
    public securities: boolean = false;
    public prevName: string;

    @ViewChild('criteriaModal') criteriaModal: ModalComponent;

    @ViewChild('criteria') criteria: CriteriaComponent;

    @ViewChild('criteriaListing') criteriaListing: CriteriaListingComponent;

    @ViewChild('resultOutput') resultOutput: ResultsComponent;

    constructor(@Host() private rootComponent: AppComponent,
        private route: ActivatedRoute,
        private router: Router,
        private toolsService: ReportingService,
        private analyticsService: AnalyticsService) {
    }

    ngOnInit() {
        this.route.params.subscribe(param => {
            this.filterId = param['id'];
            this.type = param['type'];

            this.analyticsService.sendBeacon(new GoogleAnalyticsBeacon(this.type == TargetType.Screening ? 'OnscreenCustomFilter' : 'OnscreenCustomReport',
                this.type == TargetType.Screening ? 'Screening Tool' : 'Reporting Tool', { FilterId: this.filterId }));

            //GET FILTER
            this.toolsService.getFilter(this.filterId).subscribe(data => {
                this.filter = data;
                this.securities = this.filter.portfolioId != null;

                if (this.filter.isCurrentUserOwner)
                    this.owner = StorageService.get().userInfo;
                else {
                    this.toolsService.getOwnerDetails(this.filter.ownerUserId).subscribe(ownerInfo => {
                        this.owner = ownerInfo;
                    });
                }

                this.rootComponent.finishLoading();
            });
        });

        this.updateSub = this.criteria.criteriaChanged.subscribe(data => {
            if (this.editCriteriaMode) {
                data.forEach(element => {
                    this.updateCriteria(element);
                });
            }
        });
    }

    ngOnDestroy() {
        this.updateSub.unsubscribe();
    }

    public startLoading() {
        this.rootComponent.startLoading();
    }

    public finishedLoading(data: any) {
        this.elementCount = data.count;
        this.criteriaListing.criteriaArray = data.criteria;
        this.rootComponent.finishLoading();
    }

    public cancelCriteriaModal() {
        this.criteriaModal.hide();
    }

    public resetCriteria() {
        this.criteria.resetCriteria();
    }

    public addCriteria() {
        this.editCriteriaMode = false;
        this.criteria.navigate([false, 'level1', 'default']);
        this.criteriaModal.show();
    }

    public displayResults() {
        this.resultOutput.displayResults();
    }

    public updateCriteria(criteria: BaseTemplateOutput) {
        //update criteria and reload list
        this.toolsService.updateCriteria(this.filterId, this.editingFilterGroupId, criteria).subscribe(data => {
            this.criteriaListing.getBulkCriteria(true);
            this.criteriaModal.hide();
        });
    }

    public saveCriteria() {
        //save criteria and reload list
        this.toolsService.addCriteria(this.filterId, this.criteria.selectedCriteria, this.type).subscribe(data => {
            this.criteriaListing.getBulkCriteria(true);
            this.criteriaModal.hide();
            this.criteria.resetCriteria();
        });
    }

    public editCriteria(criteriaId: string) {
        this.editCriteriaMode = true;
        this.toolsService.getCriteriaDetails(this.filterId, criteriaId);
        this.editSub = this.toolsService.details.subscribe(details => {
            this.editingFilterGroupId = details.filterGroupId;
            this.levelSub = this.toolsService.levels.subscribe(data => {                
                //find level1 and level 2 criteria ids
                this.editCriteriaLevel1Id = undefined;
                this.editCriteriaLevel2Id = undefined;
                for (var i = 0; i < data.length; i++) {
                    for (var j = 0; j < data[i].childItems.length; j++) {
                        if (data[i].childItems[j].baseCriteria.findIndex(x => x.id == details.criteriaLevel3Id) > -1) {
                            this.editCriteriaLevel1Id = data[i].id;
                            this.editCriteriaLevel2Id = data[i].childItems[j].id;
                            this.shortName = data[i].childItems[j].shortName;
                            break;
                        }
                    }
                    if (this.editCriteriaLevel1Id) break;
                }
                this.criteria.level1 = this.editCriteriaLevel1Id;
                this.criteria.level2 = this.editCriteriaLevel2Id;
                this.criteria.navigate([true, 'level1', this.editCriteriaLevel1Id, 'level2', this.editCriteriaLevel2Id, 'level3', details.criteriaLevel3Id, 'shortName', this.shortName, 'name', details.name.split('-')[0]]);
                this.criteriaModal.show();

                //unsubscribe because we do not need these details to be loaded when navigating to other criteria
                if (this.levelSub) this.levelSub.unsubscribe();
                if (this.editSub) this.editSub.unsubscribe();
            });
        });
    }

    public portfolioChanged(data: any) {
        if (data.universe) {
            this.filter.universeId = data.id;
            this.filter.universeName = data.name;
            this.filter.portfolioId = null;
            this.filter.portfolioName = null;
            this.securities = false;
        }
        else {
            this.filter.universeId = null;
            this.filter.universeName = null;
            this.filter.portfolioId = data.id;
            this.filter.portfolioName = data.name;
            this.securities = true;
        }
        this.filter.selectedPortfolioUniverse = data.selected;
        this.saveFilter(true);
    }

    public saveFilter(saveSettings: boolean) {
        this.toolsService.updateFilter(this.filter, saveSettings).subscribe(_ => {
            this.resultOutput.clearResults();
            this.elementCount = 0;
            this.editNameMode = false;
        }, error => {
            //probable error: conflict error, name already exists 
            this.rootComponent.showWarning(error.error.message, 'Warning');
        });
    }

    public setCriteriaColumns(value: CriteriaResultModel) {
        this.resultOutput.setCriteriaColumns(value ? value.items[0].criteria : []);
    }

    public shareFilter() {
        this.toolsService.shareFilter(this.filter);
    }

    public removeFilter() {
        this.toolsService.deleteFilter(this.filterId).subscribe(_ => {
            this.router.navigate(['../../'], { relativeTo: this.route });
            this.toolsService.filterRemovedNotification(this.rootComponent);
        });
    }

    public portfolioSaved() {
        this.rootComponent.showSuccess('Porfolio has been saved.', 'Success');
    }
}
